Two-factor authentication provides user identification based on the combination of two different components: i) something that the user possesses, and ii) something that the user knows. For example, a hardware or software based security token may be assigned to a user, and generate a “token code” at fixed intervals using a built-in clock and a factory-encoded random key known as the “seed”. The seed is different for each token, and is loaded into a corresponding server when the token is purchased. In order to authenticate to a secure network resource at a client system, the user must enter their username, and both the token code being displayed by the token at that moment, and a secret personal identification number (PIN). The token code and PIN entered by the user are combined to form a one-time passcode that is transmitted together with the username from the client to the server. The server authenticates the user based on the data received from the client, by computing the token code that the token is supposed to be showing at that moment in time using the server's copy of the unique seed assigned to the user's token, and comparing the computed token code value to the token code value contained in the one-time passcode received from the client system.